home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2011 November
/
CHIP_2011_11.iso
/
Programy
/
Inne
/
Gry
/
Carnage_Contest
/
scripts
/
CC Original
/
movement
/
Rope.lua
< prev
next >
Wrap
Text File
|
2010-09-29
|
12KB
|
376 lines
--------------------------------------------------------------------------------
-- Really Unoptimized Rope
-- Tobchen Carnage Contest Weapon
-- Script by Tobchen, August 2010, www.tobchen.de
--------------------------------------------------------------------------------
--[[
CHANGES BY DC August/September 2010:
- attack key for shooting and releasing
- forceframe command activated
- playercollision activated
- impact fx disabled
- item amount is decreased on use (first shot)
- rope disappears when terrain changes (e.g. mine explosion)
]]
-- Setup Tables
if cc == nil then cc = {} end
cc.rope = {}
-- Some things
cc.rope.stack = {} -- The stack contains every rope-terrain-collision-point
cc.rope.stack_top = 0
cc.rope.len = 0
cc.rope.left = 0
cc.rope.rot = 0
cc.rope.max_len = 400 -- I really think it's not wise to increase that one
cc.rope.dir = 0
cc.rope.speed = 0
-- Load & Prepare Ressources
cc.rope.gfx_icon = loadgfx("weapons/ropeicon.png")
setmidhandle(cc.rope.gfx_icon)
cc.rope.gfx_arms = loadgfx("weapons/ropearms.png")
setmidhandle(cc.rope.gfx_arms)
--------------------------------------------------------------------------------
-- Weapon: Unfinished Ninja Rope
--------------------------------------------------------------------------------
cc.rope.id=addweapon("cc.rope", "Rope (experimental! bugs!)", cc.rope.gfx_icon,1,0) -- Add Weapon (1 use, first in round 0)
-- Draw
function cc.rope.draw()
-- Draw crosshair
if weapon_mode == 0 then
-- FOR KEYBOARD-AIMING:
hudcrosshair(0, 0)
hudinfo("Press [fire] to shoot the rope, press [fire] again to release!")
-- Draw the rope
elseif weapon_mode == 1 then
setblend(blend_alpha)
setalpha(1)
setcolor(200, 200, 200)
drawline(getplayerx(0), getplayery(0), cc.rope.stack[cc.rope.stack_top].x, cc.rope.stack[cc.rope.stack_top].y, 2)
if cc.rope.stack_top > 1 then
for i=1, cc.rope.stack_top-1, 1 do
drawline(cc.rope.stack[i].x, cc.rope.stack[i].y, cc.rope.stack[i+1].x, cc.rope.stack[i+1].y, 2)
end
end
setrotation(0)
setscale(1, 1)
setcolor(255, 255, 255)
-- No player animation, but new arms
playerforceframe(0, 2)
drawimage(cc.rope.gfx_arms, getplayerx(0), getplayery(0)+3)
end
end
-- Attack
function cc.rope.attack(attack)
-- // CHANGE BY DC: Disable rope with space (requires a timer)
if weapon_timer>0 then weapon_timer=weapon_timer-1 end
-- CHANGE BY DC //
-- FOR MOUSE-AIMING:
--hudpositioning(pos_invisible)
-- FOR MOUSE-AIMING:
--if (weapon_position == 1) then
-- FOR KEYBOARD-AIMING:
-- // CHANGE BY DC: Disable rope with space (requires a timer)
--if (weapon_mode == 0 and attack == 1) then
if (weapon_mode == 0 and attack == 1 and weapon_timer<=0) then
-- CHANGE BY DC //
-- Is it a hit?
-- FOR MOUSE-AIMING:
--go_x = math.sin(math.rad(math.deg(math.atan2(getplayery(0)-weapon_y, getplayerx(0)-weapon_x))-90))
--go_y = -math.cos(math.rad(math.deg(math.atan2(getplayery(0)-weapon_y, getplayerx(0)-weapon_x))-90))
-- FOR KEYBOARD-AIMING:
go_x = math.sin(math.rad(getplayerrotation(0)))
go_y = -math.cos(math.rad(getplayerrotation(0)))
okay = 1
for i=7, cc.rope.max_len, 5 do
tmp_x = getplayerx(0)+(go_x*i)
tmp_y = getplayery(0)+(go_y*i)
if collision(col5x5, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
for j=(i-2), i+2, 1 do
tmp_x = getplayerx(0)+(go_x*j)
tmp_y = getplayery(0)+(go_y*j)
if collision(col1x1, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
-- No more player control
playercontrol(0)
weapon_mode = 1
-- // CHANGE BY DC: Decrease amount (use weapon)
if weapon_shots==0 then useweapon(1) end
-- CHANGE BY DC //
weapon_shots = weapon_shots + 1
-- Go
cc.rope.stack_top = 0
cc.rope.stack = {}
cc.rope.stack_push(tmp_x, tmp_y, 0, 0)
cc.rope.len = j
cc.rope.left = j
-- FOR MOUSE-AIMING:
--cc.rope.rot = cc.rope.normangle(math.deg(math.atan2(getplayery(0)-weapon_y, getplayerx(0)-weapon_x))+90)
-- FOR KEYBOARD-AIMING:
cc.rope.rot = cc.rope.normangle(-getplayerdirection(0)*(180-math.abs(getplayerrotation(0))))
tmp_angle = cc.rope.normangle(math.deg(math.atan2(getplayerxspeed(0), getplayeryspeed(0)))-180)-180
tmp_rot = 180-cc.rope.rot
cc.rope.speed = math.min(cc.rope.rot-tmp_angle, 180-cc.rope.rot-tmp_angle)/90.0
cc.rope.speed = cc.rope.speed*(math.sqrt((getplayerxspeed(0)^2)+(getplayeryspeed(0)^2)))/1.5
-- Visual and audioel (yeah, that word might exist) appeal
playsound(sfx_splatter5)
-- Impact FX disabled by DC
-- terrainalphaimage(gfx_blood25, cc.rope.stack[cc.rope.stack_top].x, cc.rope.stack[cc.rope.stack_top].y, 1.0, 200, 200, 200)
-- // CHANGE BY DC: Disable rope with space (requires a timer)
weapon_timer=15
-- CHANGE BY DC //
okay = 0
break
end
end
if okay == 0 then break end
end
end
-- FOR MOUSE-AIMING:
--weapon_position = 0
end
-- Rope is out
if weapon_mode == 1 then
cc.rope.rot = cc.rope.normangle(cc.rope.rot)
-- Longer
if keydown(key_down) == 1 then
cc.rope.change_length(3)
-- Shorter
elseif keydown(key_up) == 1 then
cc.rope.change_length(-3)
end
-- Turn left
if keydown(key_left) == 1 then
cc.rope.speed = cc.rope.speed + math.abs(math.cos(180-cc.rope.rot)*0.15) -- +0.08
end
-- Turn right
if keydown(key_right) == 1 then
cc.rope.speed = cc.rope.speed - math.abs(math.cos(180-cc.rope.rot)*0.15) -- 0.08
end
cc.rope.speed = cc.rope.speed+(0.15*cc.rope.sign(180-cc.rope.rot))
if math.abs(cc.rope.speed) > 5 then cc.rope.speed = 5*cc.rope.sign(cc.rope.speed) end
cc.rope.speed = cc.rope.speed*0.985
--if math.abs(cc.rope.speed) < 0.1 then cc.rope.speed = 0 end
tmp_sp = cc.rope.speed
if cc.rope.left > 150 then tmp_sp = tmp_sp*(150/cc.rope.left) end
tmp = cc.rope.precision_turn(tmp_sp)
if tmp == 1 then
cc.rope.speed = -cc.rope.speed
end
playerposition(0, cc.rope.posplx(cc.rope.rot, cc.rope.left), cc.rope.posply(cc.rope.rot, cc.rope.left))
playerpush(0, 0, 0, 1)
-- No more rope
-- // CHANGE BY DC: Disable rope with space (requires a timer)
-- if keydown(key_jump) == 1 then
if keydown(key_attack)==1 and weapon_timer<=0 then
weapon_timer=10
-- CHANGE BY DC //
playerpush(0, math.sin(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, -math.cos(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, 1)
playercontrol(1)
--useweapon(1)
weapon_mode = 0
end
-- Disable Rope (Terrain Modification)
if terrainmodification()==1 then
weapon_timer=10
playerpush(0, math.sin(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, -math.cos(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, 1)
playercontrol(1)
weapon_mode = 0
end
-- Time out
if getframesleft() < 5 then
weapon_mode = 3
playerpush(0, math.sin(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, -math.cos(math.rad(cc.rope.rot+(90*cc.rope.sign(cc.rope.rot-180))))*math.abs(cc.rope.speed)*1.5, 1)
endturn()
end
end
end
-- Turning: positive degree for left, negative for right
function cc.rope.precision_turn(degree)
tmp_rot = degree/3.0
tmp_col = 0
for i=0, 2, 1 do
col = cc.rope.turn(tmp_rot)
if col == 1 then break end
end
return col
end
function cc.rope.turn(degree)
if degree == 0.0 then return 0 end
--if (cc.rope.rot > 315 and degree > 0.0) then return 1 end
--if (cc.rope.rot < 45 and degree < 0.0) then return 1 end
old_top = cc.rope.stack_top
old_left = cc.rope.left
-- New vertices
repeat
okay = cc.rope.col(degree)
if okay == 1 then break end
if cc.rope.left < 1 then break end
until 1 == 2
if okay == 1 then
-- Player may not collide
if collision(colplayer, cc.rope.posplx(cc.rope.rot+degree, cc.rope.left), cc.rope.posply(cc.rope.rot+degree, cc.rope.left), 1, 1, 1, 0) == 0 then
cc.rope.rot = cc.rope.rot + degree
-- maybe delete some points
if cc.rope.stack_top > 1 then
repeat
if degree > 0.0 then
if (cc.rope.stack[cc.rope.stack_top].rot > cc.rope.rot-degree and cc.rope.stack[cc.rope.stack_top].rot <= cc.rope.rot) then
cc.rope.left = cc.rope.left + cc.rope.stack[cc.rope.stack_top].used
cc.rope.stack_top = cc.rope.stack_top - 1
else
break
end
else
if (cc.rope.stack[cc.rope.stack_top].rot < cc.rope.rot-degree and cc.rope.stack[cc.rope.stack_top].rot >= cc.rope.rot) then
cc.rope.left = cc.rope.left + cc.rope.stack[cc.rope.stack_top].used
cc.rope.stack_top = cc.rope.stack_top - 1
else
break
end
end
until cc.rope.stack_top == 1
end
else
cc.rope.stack_top = old_top
cc.rope.left = old_left
return 1
end
end
return 0
end
-- Change rope length, please just integers
function cc.rope.change_length(len)
if len == 0.0 then return end
if (len > 0.0 and cc.rope.len >= cc.rope.max_len) then return end
if (len < 0.0 and cc.rope.left <= 1) then return end
for i=1, math.abs(len), 1 do
if collision(colplayer, cc.rope.posplx(cc.rope.rot, cc.rope.left+(1*cc.rope.sign(len))), cc.rope.posply(cc.rope.rot, cc.rope.left+(1*cc.rope.sign(len))), 1, 1, 1, 0) == 0 then
cc.rope.len = cc.rope.len + (1*cc.rope.sign(len))
cc.rope.left = cc.rope.left + (1*cc.rope.sign(len))
else
break
end
end
end
-- Collision check
function cc.rope.col(dir)
go_x = math.sin(math.rad(cc.rope.rot+dir))
go_y = -math.cos(math.rad(cc.rope.rot+dir))
go_x_old = math.sin(math.rad(cc.rope.rot))
go_y_old = -math.cos(math.rad(cc.rope.rot))
okay = 1
if cc.rope.left >= 2 then
tmp = cc.rope.left
for i=3, tmp, 5 do
tmp_x = cc.rope.stack[cc.rope.stack_top].x+(go_x*i)
tmp_y = cc.rope.stack[cc.rope.stack_top].y+(go_y*i)
if collision(col5x5, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
for j=(i-2), i+2, 1 do
if j > cc.rope.left then break end
tmp_x = cc.rope.stack[cc.rope.stack_top].x+(go_x*j)
tmp_y = cc.rope.stack[cc.rope.stack_top].y+(go_y*j)
if collision(col5x5, tmp_x, tmp_y, 1, 1, 1, 0) == 1 then
tmp_x = cc.rope.stack[cc.rope.stack_top].x+(go_x_old*j)
tmp_y = cc.rope.stack[cc.rope.stack_top].y+(go_y_old*j)
cc.rope.stack_push(tmp_x, tmp_y, j, cc.rope.normangle(cc.rope.rot))
cc.rope.left = cc.rope.left - j
okay = 0
break
end
end
end
if okay == 0 then break end
end
end
return okay
end
-- Some simple stack functions (stack, using an array)
function cc.rope.stack_push(fx, fy, fu, fr)
cc.rope.stack_top = cc.rope.stack_top + 1
cc.rope.stack[cc.rope.stack_top] = {}
cc.rope.stack[cc.rope.stack_top].x = fx
cc.rope.stack[cc.rope.stack_top].y = fy
cc.rope.stack[cc.rope.stack_top].used = fu
cc.rope.stack[cc.rope.stack_top].rot = fr
end
-- Get relative
function cc.rope.getanglex(rot, len)
return math.sin(math.rad(rot))*len
end
function cc.rope.getangley(rot, len)
return -math.cos(math.rad(rot))*len
end
-- Position player
function cc.rope.posplx(rot, len)
return cc.rope.stack[cc.rope.stack_top].x+cc.rope.getanglex(rot , len)
end
function cc.rope.posply(rot, len)
return cc.rope.stack[cc.rope.stack_top].y+cc.rope.getangley(rot, len)
end
-- Norm the angle
function cc.rope.normangle(rot)
if rot < 0 then
rot = rot + 360
cc.rope.normangle(rot)
elseif rot > 360 then
rot = rot - 360
cc.rope.normangle(rot)
end
return rot
end
-- Sign
function cc.rope.sign(number)
if number < 0.0 then return -1 end
return 1
end